package com.monlyu.bo;

import java.util.Date;
import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.criterion.Order;
import org.hibernate.criterion.Restrictions;
import org.springframework.stereotype.Repository;

import com.monlyu.bean.Page;
import com.monlyu.bean.Pages;
import com.monlyu.model.QueryDeviceUseModel;
import com.monlyu.util.DateUtil;
import com.monlyu.util.StringUtil;
import com.monlyu.util.WebOptUtil;
import com.monlyu.vo.DeviceUse;
import com.monlyu.vo.Devices;
import com.monlyu.vo.OuterApp;
import com.monlyu.vo.User;

/**
 * @author SongJun
 * @since 2010-2-23
 * @description
 */
@Repository(value = "deviceuseBo")
public class DeviceuseBo extends BaseBo {

	private DevicesBo devicesBo;

	public void setDevicesBo(DevicesBo devicesBo) {
		this.devicesBo = devicesBo;
	}

	public void updateDeviceuse(DeviceUse du) {
		DeviceUse dbDeviceuse = getDeviceUseById(du.getId());
		dbDeviceuse.setDelaydescribe(du.getDelaydescribe());
		dbDeviceuse.setDeviceaffix(du.getDeviceaffix());
		dbDeviceuse.setDeviceid(du.getDeviceid());
		dbDeviceuse.setPlan_enddate(du.getPlan_enddate());
		dbDeviceuse.setReal_enddate(du.getReal_enddate());
		dbDeviceuse.setUse_startdate(du.getUse_startdate());
		dbDeviceuse.setUsedescribe(du.getUsedescribe());
		dbDeviceuse.setUserApp(du.getUserApp());
		dbDeviceuse.setUserReceive(du.getUserReceive());
		dao.update(dbDeviceuse);
	}

	public DeviceUse getDeviceUseById(long id) {
		String hql = "from com.monlyu.vo.DeviceUse d where d.id =?";
		return (DeviceUse) dao.findOne(hql, id);
	}

	public String getDeviceuseNo() {
		String stime = DateUtil.nowtime2Str();
		return stime.replaceAll("-", "").replaceAll(" ", "")
				.replaceAll(":", "");
	}

	/**
	 * @author SongJun
	 * @since 2010-3-4
	 * @description 所有设备外借申请记录
	 */
	public Pages<DeviceUse> getDeviceuseList(Page page) {
		Criteria criteria = dao.initCriteria(DeviceUse.class);
		// criteria.createAlias("userReceive", "userReceive");
		// criteria.add(Restrictions.isNotNull("userReceive"));
		// if (!StringUtil.isEmpty(page.getKey())) {
		// criteria.add(Restrictions.like("deviceuseNo", page.getKey().trim(),
		// MatchMode.ANYWHERE));
		// }
		criteria.addOrder(Order.asc("id"));
		return findByCriteria(page.getNo(), page.getSize(), criteria);
	}

	public Pages<DeviceUse> getQueryDeviceuse(QueryDeviceUseModel qdum,
			Page page) {
		Criteria criteria = dao.initCriteria(DeviceUse.class);
		if (qdum.getDeviceId() != null
				|| !StringUtil.isEmpty(qdum.getDeviceName())) {
			criteria.createAlias("deviceid", "deviceid");
			if (qdum.getDeviceId() != null) {
				criteria
						.add(Restrictions.eq("deviceid.id", qdum.getDeviceId()));
			}
			if (!StringUtil.isEmpty(qdum.getDeviceName())) {
				criteria.add(Restrictions.eq("deviceid.deviceName", qdum
						.getDeviceName()));
			}
		}
		if (qdum.getUserAppId() != null) {
			criteria.createAlias("userApp", "userApp");
			criteria.add(Restrictions.eq("userApp.id", qdum.getUserAppId()));
		}
		if (qdum.getUserReceiveId() != null) {
			criteria.createAlias("userReceive", "userReceive");
			criteria.add(Restrictions.isNotNull("userReceive"));
			criteria.add(Restrictions.eq("userReceive.id", qdum
					.getUserReceiveId()));
		}
		// else{
		// criteria.createAlias("userReceive", "userReceive");
		// criteria.add(Restrictions.isNotNull("userReceive"));
		// }
		if (qdum.getUserReturnId() != null) {
			criteria.createAlias("userReturn", "userReturn");
			criteria.add(Restrictions.eq("userReturn.id", qdum
					.getUserReturnId()));
		}
		if (qdum.getUserReturnId() != null) {
			criteria.createAlias("userReturn", "userReturn");
			criteria.add(Restrictions.eq("userReturn.id", qdum
					.getUserReturnId()));
		}
		if (qdum.getUserAuthId() != null) {
			criteria.createAlias("userAuth", "userAuth");
			criteria.add(Restrictions.eq("userAuth.id", qdum.getUserAuthId()));
		}
		if (qdum.getBeg_date() != null) {
			criteria.add(Restrictions.gt("use_startdate", qdum.getBeg_date()));
		}
		if (qdum.getEnd_date() != null) {
			criteria.add(Restrictions.lt("plan_enddate", qdum.getEnd_date()));
		}
		criteria.addOrder(Order.asc("id"));
		return findByCriteria(page.getNo(), page.getSize(), criteria);
	}

	/**
	 * @author SongJun
	 * @since 2010-2-26
	 * @description 所有目前可供使用的设备信息
	 */
	public Pages<Devices> getDeviceUseAble(Page page) {
		Criteria criteria = dao.initCriteria(Devices.class);
		criteria.add(Restrictions.eq("deviceState", Devices.DEVICESTATUS_IN));
		criteria.add(Restrictions.eq("enable", true));
		criteria.addOrder(Order.asc("deviceName"));
		return findByCriteria(page.getNo(), page.getSize(), criteria);
	}

	/**
	 * 获取可用的设备编号和字符串 获取 ID.
	 */
	@SuppressWarnings("unchecked")
	public List<Devices> getEnableDevices() {
		String hql = "from com.monlyu.vo.Devices d where d.deviceState =? and d.enable = ? order by d.devicetype asc";
		return dao.find(hql, Devices.DEVICESTATUS_IN, true);
	}

	/**
	 * @author SongJun
	 * @since 2010-3-6
	 * @description 获取当前用户列表可供设备申请时选择
	 */
	public Pages<User> getUserList(Page page) {
		Criteria criteria = dao.initCriteria(User.class);
		criteria.addOrder(Order.asc("id"));
		return findByCriteria(page.getNo(), page.getSize(), criteria);
	}

	/**
	 * @author SongJun
	 * @since 2010-2-27
	 * @description 归还时用 所有已经外借的设备
	 */
	public Pages<DeviceUse> getDeviceused(Page page) {
		Criteria criteria = dao.initCriteria(DeviceUse.class);
		criteria.add(Restrictions.eq("hasReturn", false));
		criteria.add(Restrictions.eq("hasOff", false));
		criteria.addOrder(Order.asc("id"));
		return findByCriteria(page.getNo(), page.getSize(), criteria);
	}

	/**
	 * @author SongJun
	 * @since 2010-2-28
	 * @description 设备归还
	 */
	public void devicesRet(DeviceUse deviceuse, String... retduid) {
		if (null != deviceuse && retduid.length > 0) {
			for (String id : retduid) {
				DeviceUse dbdu = getDeviceUseById(new Long(id));
				dbdu.setReal_enddate(deviceuse.getReal_enddate());
				dbdu.setDelaydescribe(deviceuse.getDelaydescribe());
				dbdu.setHasReturn(true);
				Devices dbds = dbdu.getDeviceid();
				dbds.setDeviceState(Devices.DEVICESTATUS_IN);
				dao.update(dbdu);
				dao.update(dbds);
			}
		}
	}

	/**
	 * @author SongJun
	 * @since 2010-3-4
	 * @description 注销当前的设备外借申请记录
	 */
	public void OffDeviceUse(DeviceUse deviceuse) {
		DeviceUse dbdu = getDeviceUseById(deviceuse.getId());
		dbdu.setHasOff(true);
		Devices dbds = dbdu.getDeviceid();
		dbds.setDeviceState(Devices.DEVICESTATUS_IN);
		dao.update(dbdu);
		dao.update(dbds);
	}

	/**
	 * @author SongJun
	 * @since 2010-3-9
	 * @description 根据设备申请号和 设备申请人返回申请设备列表或者设备外借
	 */
	@SuppressWarnings("unchecked")
	public List<DeviceUse> getAppDeviceByUserNo(long deviceState, Long userid,
			Long appNo) {
		String hql = "from com.monlyu.vo.DeviceUse d where (d.userReceive.id is null or d.userReturn.id is null)"
				+ " and d.deviceid.deviceState = ?";
		if (null != userid) {
			hql += " and d.userApp.id = ?";
			if (!StringUtil.isEmpty(appNo)) {
				hql += " and d.outapp.id = ?";
				return dao.find(hql, deviceState, userid, appNo);
			} else {
				return dao.find(hql, deviceState, userid);
			}
		} else {
			if (null != appNo) {
				hql += " and d.outapp.id = ?";
				return dao.find(hql, deviceState, appNo);
			} else {
				return null;
			}
		}

	}

	/**
	 * @author SongJun
	 * @since 2010-3-9
	 * @description 封装设备申请的信息
	 */
	public String packDeviceInfo(List<DeviceUse> dus) {
		if (null != dus) {
			StringBuilder sb = new StringBuilder();
			for (DeviceUse du : dus) {
				sb = sb.append(du.getDeviceid().getDeviceName()).append(" | ");
			}
			String str = sb.toString();
			return str;
			// return str.substring(0, str.lastIndexOf(";")-1);
		} else {
			return null;
		}
	}

	/**
	 * @author SongJun
	 * @since 2010-3-10
	 * @description 设备领用手续
	 */
	public void deviceRece(List<DeviceUse> dus, DeviceUse du, Long receUserid) {
		// List<DeviceUse> dus = getAppDeviceByUserNo(appUserId, null);
		User receUser = getUserById(receUserid);
		User curUser = WebOptUtil.curUser();
		du.setApporUpDate(DateUtil.now());
		du.setReceiveDate(DateUtil.now());
		du.setUserReceive(receUser);
		du.setUserRelease(curUser);
		for (DeviceUse deviceuse : dus) {
			toRecedevices(du, deviceuse.getId());
		}
	}

	/**
	 * @author SongJun
	 * @since 2010-3-10
	 * @description 获取user通过id
	 */
	public User getUserById(long id) {
		String hql = "from com.monlyu.vo.User u where u.id =?";
		return (User) dao.findOne(hql, id);
	}

	/**
	 * @author SongJun
	 * @since 2010-3-10
	 * @description 设备领取时具体更新的一个设备领取信息
	 */
	public void toRecedevices(DeviceUse deviceuse, Long duid) {
		DeviceUse dbdu = getDeviceUseById(duid);
		Devices dbds = dbdu.getDeviceid();
		dbds.setDeviceState(Devices.DEVICESTATUS_OUT);// 外借已经领取
		dbdu.setApporUpDate(deviceuse.getApporUpDate());
		dbdu.setUserReceive(deviceuse.getUserReceive());
		dbdu.setUserRelease(deviceuse.getUserRelease());
		dbdu.setUsedescribe(deviceuse.getUsedescribe());
		dbdu.setReceiveDate(deviceuse.getReceiveDate());
		dbdu.setUseAddr(deviceuse.getUseAddr());
		dbdu.setHasReturn(false);
		dao.update(dbdu);
		dao.update(dbds);
	}

	/**
	 * @author SongJun
	 * @since 2010-3-11
	 * @description 根据申请号和归还的设备信息来逐一的规划 x:y:z;m:n:d;
	 */
	public int toReturnDevic(Long appNo, String returnInfo, DeviceUse du,
			Long retUserid, Long authUserid) {
		String deviceid = "";
		String fg = "";
		String desc = " ";
		String[] di = analyseReturnInfo(returnInfo, ";");
		User retUser = getUserById(retUserid);
		User authUser = getUserById(authUserid);
		Date realendate = du.getReal_enddate();
		for (String str : di) {
			String[] info = analyseReturnInfo(str, ":");
			deviceid = info[0];
			fg = info[1];
			if (info.length == 3) {
				desc = fg.equals("true") ? " " : info[2];
			}
			DeviceUse dbdu = getDeviceUse(appNo, new Long(deviceid));
			dbdu.setReal_enddate(realendate);
			dbdu.setUserAuth(authUser);
			dbdu.setUserUpdate(WebOptUtil.curUser());
			dbdu.setUserReturn(retUser);
			dbdu.setHasNormal(fg.equals("true"));
			dbdu.setNoNormalDesc(desc);
			dbdu.setHasReturn(true);
			dbdu.setApporUpDate(DateUtil.now());
			dbdu.setDelaydescribe(du.getDelaydescribe());
			Devices dbds = dbdu.getDeviceid();
			dbds.setDeviceState(fg.equals("true") ? Devices.DEVICESTATUS_IN
					: Devices.DEVICESTATUS_BAD);// 32正常入库；35设备损坏入库
			dao.update(dbdu);
			dao.update(dbds);
		}
		return di.length;
	}

	/**
	 * @author SongJun
	 * @since 2010-3-13
	 * @description 设备归还时，对归还设备的信息进行解析
	 */
	public static String[] analyseReturnInfo(String str, String sign) {
		if (!StringUtil.isEmpty(str)) {
			String[] info = str.split(sign);
			return info;
		}
		return null;
	}

	public DeviceUse getDeviceUse(Long appNo, Long deviceid) {
		String hql = "from com.monlyu.vo.DeviceUse d where d.outapp.id =?  and d.deviceid.id=?";
		return (DeviceUse) dao.findOne(hql, appNo, deviceid);
	}

	/**
	 * @param app
	 *            外出申请对象 包含了申请人,申请开始时间
	 * @param devices
	 *            设备的IDlist TODO 申请之后把状态改为 冻结
	 * @since 2010-3-13
	 * @author songjun 已经修改完成
	 */
	public void addDevice(OuterApp app, List<Long> devices) {
		User appUser = app.getApper();
		Date s_date = app.getBegin();
		Date e_date = app.getEnd();
		for (Long deid : devices) {
			DeviceUse du = new DeviceUse();
			Devices dbds = devicesBo.getDevicesById(deid);
			dbds.setDeviceState(Devices.DEVICESTATUS_APP);
			du.setDeviceid(dbds);
			du.setOutapp(app);
			du.setUserApp(appUser);
			du.setUse_startdate(s_date);
			du.setPlan_enddate(e_date);
			du.setApporUpDate(DateUtil.now());
			dao.update(dbds);
			dao.insertOrUpdate(du);
		}
	}

	// 在第二次更新前，删除前面创建的。
	public void delDevice(OuterApp app) {
		for (DeviceUse device : dao.find(DeviceUse.class, "outapp.id", app
				.getId())) {
			String update = "update com.monlyu.vo.Devices t set t.deviceState=? where t.id=?";
			dao.execute(update, Devices.DEVICESTATUS_IN, device.getDeviceid()
					.getId());
			dao.delete(device);
		}
	}

	/**
	 * @author SongJun
	 * @since 2010-3-12
	 * @description public static void main(String[] args){ String str =
	 *              "x:y:z;m:n:d;"; String[] stt = analyseReturnInfo(str, ";");
	 *              for(String s:stt){ System.out.println(s); }
	 *              System.out.println(stt.length); }
	 */

	/**
	 * 根据APPID获取设备类型
	 * 
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public List<String> findDusedB(Long Outappid) {
		String hql = "select CONCAT(CONCAT(m.deviceid.deviceName,'-'),m.deviceid.deviceNo) from com.monlyu.vo.DeviceUse m where m.outapp.id=?";
		return dao.find(hql, Outappid);
	}
}
